package com.hrhx.springboot.crawler.plugins.net.selenium;

import cn.edu.hfut.dmic.webcollector.model.CrawlDatum;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.net.OkHttpRequester;

import com.hrhx.springboot.crawler.plugins.net.webdriver.ChromeWebDriverFactory;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.WebDriver;

import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author duhongming
 * @version 1.0
 * @description 谷歌浏览器驱动请求器
 * @date 2019/11/11 14:22
 */
@Slf4j
public class ChromeDriverRequest extends OkHttpRequester {

    private Boolean useProxy;

    //每一个间隔休息一秒
    @Setter
    private Integer sleepTime = 1000;

    //20个 重启浏览器
    @Setter
    private Integer driverCount = 20;

    /**
     * 默认Chrome浏览器请求不使用代理
     */
    public ChromeDriverRequest() {
        this.useProxy = false;
    }

    public ChromeDriverRequest(Boolean useProxy) {
        this.useProxy = useProxy;
    }

    /**
     * 重试计数Key
     */
    public static final String COUNT_KEY = "count";

    /**
     * 失败重试次数为3次
     */
    public static final Integer REPEAT_COUNT = 3;

    /**
     * 请求URL计数，总请求一个浏览器实例会发生报错，为了解决该问题，每20请求一个实例
     */
    private static AtomicInteger count = new AtomicInteger(0);

    /**
     * Web浏览器驱动
     */
    private static WebDriver driver;

    @Override
    public Page getResponse(CrawlDatum datum) {
        //每20个请求，重新注册新浏览器实例
        if (count.getAndIncrement() % 50 == 0) {
            if(Objects.nonNull(driver)){
                driver.quit();
            }
            driver = ChromeWebDriverFactory.me.getNewInstance(useProxy);
        }

        //使用内置的meta来计数
        if (StringUtils.isBlank(datum.meta(COUNT_KEY))) {
            datum.meta(COUNT_KEY, 0);
        } else {
            datum.meta(COUNT_KEY, datum.metaAsInt(COUNT_KEY) + 1);
        }

        //失败次数超过REPEAT_COUNT，返回New Page();
        if (datum.metaAsInt(COUNT_KEY) > REPEAT_COUNT) {
            return new Page(datum, null, null);
        }

        //递归重试逻辑
        try {
            driver.get(datum.url());
            TimeUnit.MILLISECONDS.sleep(sleepTime);
        } catch (Exception e) {
            log.error("第" + datum.meta(COUNT_KEY) + "次请求异常：", e);
            System.exit(0);
//            driver = ChromeWebDriver.getInstance();
//            getResponse(datum);
        }

        //重新封装为Page对象
        Page page = new Page(datum, "", driver.getPageSource().getBytes());
        page.charset("UTF-8");

        return page;
    }
}